﻿#pragma once
#include "GameCoreScriptBinder.h"
#include "UISystem.h"

_NAMESPACE_BEGIN

/// GUI窗口基类，为了便于脚本和其他处使用UI而对CEGUI进行的再封装

class WidgetWindow
{
public:
	
	/// 默认构造，创建空窗口
	WidgetWindow():window(NULL){}

	/// 创建一个默认皮肤的窗口，并设置默认的大小和位置
	/// 默认大小为：整个客户区窗口大小
	/// 默认位置为：客户区窗口的左上角
	/// \param[in] name 用于唯一标识窗口的名称
	WidgetWindow(CONST_REF(string) name);
	
	/// 析构，尚未重写
	virtual ~WidgetWindow(){}

public:
	
	/// 返回对应CEGUI的窗口对象
	CEGUI::Window* GetWindow(){return window;}

	/// 设置窗口尺寸，范围为0-1，即整个窗口客户区宽高对应的比例
	/// \param[in] w 宽度
	/// \param[in] h 高度
	void SetSize(float w, float h);	

	/// 设置窗口所在位置，坐标按窗口左上角起开始计算
	/// \param[in] x x坐标
	/// \param[in] y y坐标
	void SetPos(float x, float y);			

	/// 设置窗口所在未知，坐标按窗口控件的中心点起开始计算
	/// \param[in] x x坐标
	/// \param[in] y y坐标
	void SetCenterPos(float x, float y);	

	/// 本窗口是否响应鼠标点击事件
	/// \param[in] val true为响应事件并接受UI控件做出回应，false则相反
	void SetClickEnabled(bool val);											

	/// 设置窗口的属性
	/// \param[in] name 对应CEGUI的窗口属性名
	/// \param[in] val 对应的属性的值
	void SetProperty(CONST_REF(string) name, CONST_REF(string) val);	
	
	/// 为窗口设置图片
	/// \param[in] name 已经在UiSystem单体对象中添加的图片资源的唯一标识名称
	void SetImage(CONST_REF(string) name);

	/// 设置窗口是否可见
	/// \param[in] val true为可见，false为不可见，同时屏蔽窗口的一切事件响应
	void SetVisible(bool val);

	/// 当前窗口是否可见
	bool IsVisible();

	/// 添加子窗口
	/// \param[in] win WidgetWindow对象的指针
	void AddChildWindow(WidgetWindow* win);

	/// 载入皮肤
	/// \param[in] name 皮肤资源名
	void LoadLayout(CONST_REF(string) name);

	/// 如果窗口可以的话，设置文字
	/// 具体视控件名而定，可能是标题，按钮内容，等等
	/// \param[in] name 文字内容
	void SetText(CONST_REF(string) name);
	
	/// Z-order的改变是否对窗口有效
	/// \param[in] name 设置
	void SetZOrderingEnabled(bool setting);

	///激活窗口
	void Activate();

protected:

	/// CEGUI的窗口对象指针
	CEGUI::Window* window;
};

//////////////////////////////////////////////////////////////////////////

/// 按钮类

class WidgetButton : public WidgetWindow
{
public:
	
	/// 创建一个按钮
	/// \param[in] text 按钮的文字内容
	/// \param[in] name 用于唯一标识按钮控件的名称
	WidgetButton(CONST_REF(string) text, CONST_REF(string) name);
	
	/// 从传入的CEGUI::Window*指针创建按钮
	/// \param[in] win CEGUI::Window* 指针
	WidgetButton(CEGUI::Window* win);
	
	/// 析构
	virtual ~WidgetButton(){};

public:
	
	/// 响应了单击事件的回调函数，由CEGUI系统调用
	bool Event(const CEGUI::EventArgs& e);

public:
	
	/// 在脚本中实现观察者的对象，响应按钮的单击事件
	ASEvent	clickSlot;	

protected:

	/// 按钮的文字内容
	string buttonText;
	
};


//////////////////////////////////////////////////////////////////////////

/// 单选按钮类
class WidgetRadioButton : public WidgetWindow
{
public:

	/// 创建一个单选按钮
	/// \param[in] name 用于唯一标识按钮控件的名称
	WidgetRadioButton(CONST_REF(string) name);

	/// 从传入的CEGUI::Window*指针创建按钮
	/// \param[in] win CEGUI::Window* 指针
	WidgetRadioButton(CEGUI::Window* win);

	/// 析构
	virtual ~WidgetRadioButton(){};

public:

	/// 响应了单击事件的回调函数，由CEGUI系统调用
	bool Event(const CEGUI::EventArgs& e);

public:

	/// 在脚本中实现观察者的对象，响应按钮的单击事件
	ASEvent	clickSlot;	

};

//////////////////////////////////////////////////////////////////////////

/// 编辑框类
class WidgetEditBox : public WidgetWindow
{
public:

	/// 创建一个编辑框
	/// \param[in] name 用于唯一标识编辑框控件的名称
	WidgetEditBox(CONST_REF(string) name);

	/// 从传入的CEGUI::Window*指针创建编辑框
	/// \param[in] win CEGUI::Window* 指针
	WidgetEditBox(CEGUI::Window* win);

	/// 析构
	virtual ~WidgetEditBox(){};

public:

	/// 响应了单击事件的回调函数，由CEGUI系统调用
	bool Event(const CEGUI::EventArgs& e);

	/// 限定输入字符串
	void  setValidationString (const String &validation_string);

	/// 将编辑框设置为密码属性
	void setTextMasked(bool setting);
public:

	/// 在脚本中实现观察者的对象，响应编辑框的单击事件
	ASEvent	clickSlot;

protected:
	string InputText;
};


//////////////////////////////////////////////////////////////////////////

/// 列表框类

class WidgetListBox : public WidgetWindow
{
public:

	/// 创建一个列表框
	/// \param[in] text 列表框的文字内容
	/// \param[in] name 用于唯一标识列表框控件的名称
	WidgetListBox( CONST_REF(string) name);
	
	/// 从传入的CEGUI::ListBox*指针创建列表框
	/// \param[in] win CEGUI::Window* 指针
	WidgetListBox( CEGUI::Window* win);
	
	/// 析构
	virtual ~WidgetListBox(){};

public:

	/// 改变当前选择项的回调，由CEGUI系统调用
	bool ChangeSelEvent(const CEGUI::EventArgs& e);

	/// 当前选择了几个选项
	/// \return 当前选择的项数，-1为当前未选择任何选择项
	int GetSelectedCount();
	
	/// 获取当前选项内容
	/// param[out] text 返回当前选择的选项的文字内容
	void GetCurtSel(string& text);

	/// 增加选项
	/// param[in] text 新选项的文字内容
	/// param[in] id 新选项的id号
	void AddItem(CONST_REF(string)text, int id);
	
	/// 清除所有项
	void ClearItems();

public:

	/// 在脚本中实现观察者的对象，响应选项改变的事件
	ASEvent	changeSelSlot;	

protected:
	string buttonText;

};

//////////////////////////////////////////////////////////////////////////

/// 组合列表框类

class WidgetComboBox : public WidgetWindow
{
public:

	/// 创建一个组合列表框
	/// \param[in] text 组合列表框的文字内容
	/// \param[in] name 用于唯一标识组合列表框控件的名称
	WidgetComboBox(CONST_REF(string) name);
	
	/// 从传入的CEGUI::ComboBox*指针创建列表框
	/// \param[in] win CEGUI::Window* 指针
	WidgetComboBox(CEGUI::Window* win);

	/// 析构
	virtual ~WidgetComboBox(){};

public:

	/// 改变当前选择项的回调，由CEGUI系统调用
	bool ChangeSelEvent(const CEGUI::EventArgs& e);
	
	/// 清除所有选择项
	void ClearItems();

	/// 增加新选择项
	/// \param[in] text 新选择项的文字内容
	/// \param[in] id 新选择项的id号
	void AddItem(CONST_REF(string)text, int id);

	/// 获取当前选项内容
	/// \param[out] text 返回当前选择的项的文字内容
	void GetCurtSel(string& text);

public:
	
	/// 在脚本中实现观察者的对象，响应选项改变的事件
	ASEvent	changeSelSlot;	

protected:
	string buttonText;

};

//////////////////////////////////////////////////////////////////////////

/// 组合列表框类

class WidgetMultilineList : public WidgetWindow
{
public:

	/// 创建一个组合列表框
	/// \param[in] text 组合列表框的文字内容
	/// \param[in] name 用于唯一标识组合列表框控件的名称
	WidgetMultilineList(CONST_REF(string) name);

	/// 从传入的CEGUI::ComboBox*指针创建列表框
	/// \param[in] win CEGUI::Window* 指针
	WidgetMultilineList(CEGUI::Window* win);

	/// 析构
	virtual ~WidgetMultilineList(){};

public:

	/// 清除所有选择项
	void ClearItems();

	/// 设置选择项
	/// \param[in] text 选择项的文字内容
	/// \param[in] row 选择项的行号
	/// \param[in] col 选择项的列号
	void SetRowItem(CONST_REF(string)text, int row, int col);

	/// 增加新行
	/// \param[in] row 选择项的行号
	void AddRow(int row);

	/// 获取当前选项内容
	/// \param[out] text 返回当前选择的项的文字内容
	/// \param[in] colOff 列偏移值
	void GetCurtSel(string& text, int colOff);

	/// 当前选择了几个选项
	/// \return 当前选择的项数，-1为当前未选择任何选择项
	int GetSelectedCount();

public:

	/// 在脚本中实现观察者的对象，响应选项改变的事件
	ASEvent	changeSelSlot;	

protected:
	string buttonText;

};

_NAMESPACE_END